#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include "base.h"
#include "my_serialize.h"

 
int serialize_filename(char* buffer,const struct C2S_filename* msg){
    if(buffer == NULL || msg == NULL || msg->type != C2S_FILENAME || msg->filename == NULL){
        return -1;
    }
    int offset = serialize_int(buffer,0,msg->type);
    offset = serialize_string(buffer,offset,msg->filename);
    return offset;
}

int serialize_fileinfo(char* buffer,const struct S2C_fileinfo* msg){
    if(buffer == NULL || msg == NULL || msg->type != S2C_FILEINFO){
        return -1;
    }
    int offset = serialize_int(buffer,0,msg->type);
    offset = serialize_uint64_t(buffer,offset,msg->size);
    return offset;
}

int serialize_loadinfo(char* buffer,const struct C2S_loadinfo* msg){
    if(buffer == NULL || msg == NULL || msg->type != C2S_LOADINFO){
        return -1;
    }
    int offset = serialize_int(buffer,0,msg->type);
    offset = serialize_string(buffer,offset,msg->filepath);
    offset = serialize_uint64_t(buffer,offset,msg->offset);
    offset = serialize_uint64_t(buffer,offset,msg->block_size);
    return offset;
}

int serialize_fileblock(char* buffer,const struct S2C_file_block* msg,int n){
    if(buffer == NULL || msg == NULL || msg->type != S2C_FILEBLOCK){
        return -1;
    }
    int offset = serialize_int(buffer,0,msg->type);
    offset = serialize_uint64_t(buffer,offset,msg->offset);
    offset = serialize_arr_ch(buffer,offset,msg->content,n);
    return offset;
}

int unserialize_filename(struct C2S_filename* msg,const char* buffer){
    if(buffer == NULL || msg == NULL){
        return -1;
    }
    int offset = unserialize_int(&msg->type,buffer,0);
    unserialize_string(msg->filename,buffer,offset);
    return 0;
}

int unserialize_fileinfo(struct S2C_fileinfo* msg,const char* buffer){
    if(buffer == NULL || msg == NULL){
        return -1;
    }
    int offset = unserialize_int(&msg->type,buffer,0);
    unserialize_uint64_t(&msg->size,buffer,offset);
    return 0;
}

int unserialize_loadinfo(struct C2S_loadinfo* msg,const char* buffer){
    if(buffer == NULL || msg == NULL){
        return -1;
    }
    int offset = unserialize_int(&msg->type,buffer,0);
    offset = unserialize_string(msg->filepath,buffer,offset);
    offset = unserialize_uint64_t(&msg->offset,buffer,offset);
    offset = unserialize_uint64_t(&msg->block_size,buffer,offset);
    return 0;
}

//返回content字符数组的长度
int unserialize_fileblock(struct S2C_file_block* msg,const char* buffer){
    if(buffer == NULL || msg == NULL){
        return -1;
    }
    int offset = unserialize_int(&msg->type,buffer,0);
    offset = unserialize_uint64_t(&msg->offset,buffer,offset);
    int len_content = 0;
    offset = unserialize_arr_ch(msg->content,&len_content,buffer,offset);
    return len_content;
}

//函数:创建buftosend
void* create_buftosend(int size){
    char* p = malloc(size);
    return p;
}

//函数:释放buftosend
void free_buftosend(char** buftosend){
    free(*buftosend);
    *buftosend = NULL;
}

//解决粘包,返回是否成功
char* addlength(const char* buffer,int size){
    if(buffer == NULL){
        return NULL;
    }
    char* buftosend = create_buftosend(size+sizeof(uint32_t));
    if(buftosend == NULL){
        return NULL;
    }
    uint32_t tmp = htonl(size);
    memcpy(buftosend,&tmp,sizeof(uint32_t));
    memcpy(buftosend+sizeof(uint32_t),buffer,size);
    return buftosend;
}

//接受消息头,返回消息大小
int recv_header(int sockfd){
    if(sockfd<0){
        return -1;
    }
    int len = 0;
    recv(sockfd,&len,sizeof(int),0);
    return ntohl(len);
}
